package com.mall.shopping.services;

import com.mall.commons.tool.exception.BizException;
import com.mall.shopping.ICartService;
import com.mall.shopping.constants.ShoppingRetCode;
import com.mall.shopping.converter.CartItemConverter;
import com.mall.shopping.dal.entitys.Item;
import com.mall.shopping.dal.persistence.ItemMapper;
import com.mall.shopping.dto.*;
import com.mall.shopping.utils.ExceptionProcessorUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;

/**
 * 购物车服务实现类
 * @author Javid Xi
 * @version 1.0
 * @since 2021/7/22
 */
@Slf4j
@Service
@Component
public class CartServiceImpl implements ICartService {

    /**
     * 连接redis客户端
     */
    @Autowired
    RedissonClient redissonClient;

    @Autowired
    ItemMapper itemMapper;

    /**
     * 获得购物车商品列表
     * @param request 请求参数
     * @return CartListByIdResponse
     */
    @Override
    public CartListByIdResponse getCartListById(CartListByIdRequest request) {
        // 响应封装类
        CartListByIdResponse response = new CartListByIdResponse();

        try {
            // 根据用户 id 从 redis 取得购物车map
            String userId = String.valueOf(request.getUserId());
            RMap<Object, Object> itemsMap = redissonClient.getMap(userId);
            // 封装购物车链表
            ArrayList<CartProductDto> cartProductDtos = new ArrayList<>();
            for (Map.Entry<Object, Object> entry : itemsMap.entrySet()) {
                cartProductDtos.add((CartProductDto) entry.getValue());
            }
            // 封装响应
            response.setCartProductDtos(cartProductDtos);
            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            log.error("CartServiceImpl.getCartListById Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    /**
     * 添加商品到购物车
     * @param request 请求参数
     * @return AddCartResponse
     */
    @Override
    public AddCartResponse addToCart(AddCartRequest request) {
        // 响应封装类
        AddCartResponse response = new AddCartResponse();

        try {
            String userId = String.valueOf(request.getUserId());
            String itemId = String.valueOf(request.getItemId());
            Integer num = request.getNum();

            RMap<Object, Object> itemsMap = redissonClient.getMap(userId);
            Item item = itemMapper.selectByPrimaryKey(itemId);

            // 加入购物车
            CartProductDto cartProductDto = null;
            if (!itemsMap.containsKey(itemId)) { // 不存在此商品id，则新增
                // 对象转换
                cartProductDto = CartItemConverter.item2Dto(item);
                Long productNum = num.longValue();
                cartProductDto.setProductNum(productNum);
            } else { // 不存在此商品id，则更新数量
                cartProductDto= (CartProductDto) itemsMap.get(itemId);
                cartProductDto.setProductNum(num + cartProductDto.getProductNum());
            }
            cartProductDto.setChecked("true");
            // 加入购物车map
            itemsMap.fastPut(itemId, cartProductDto);
            // 封装响应
            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        }catch (Exception e){
            log.error("ICatServiceImpl.addToCart Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    /**
     * 更新购物车中商品的数量
     * @param request 请求参数
     * @return UpdateCartNumResponse
     */
    @Override
    public UpdateCartNumResponse updateCartNum(UpdateCartNumRequest request) {
        // 响应封装类
        UpdateCartNumResponse response = new UpdateCartNumResponse();

        try {
            // 解析请求参数
            String userId = String.valueOf(request.getUserId());
            String itemId = String.valueOf(request.getItemId());
            Integer num = request.getNum();
            String checked = request.getChecked();

            // 获取购物车map
            RMap<Object, Object> itemsMap = redissonClient.getMap(userId);
            // 获取更新的购物车项目
            CartProductDto cartProductDto = (CartProductDto) itemsMap.get(itemId);
            // 检验是否存在
            if(cartProductDto == null){
                throw new BizException(ShoppingRetCode.PARAMETER_ERROR.getCode(), ShoppingRetCode.PARAMETER_ERROR.getMessage());
            }

            // 更新此购物车项目
            cartProductDto.setProductNum(num.longValue());
            cartProductDto.setChecked(checked);
            // 更新购物车map
            itemsMap.fastPut(itemId, cartProductDto);
            // 封装响应
            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());

        }catch (Exception e){
            log.error("ICatServiceImpl.updateCartNum Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    /**
     * 选择购物车中的所有商品
     * @param request 请求参数
     * @return CheckAllItemResponse
     */
    @Override
    public CheckAllItemResponse checkAllCartItem(CheckAllItemRequest request) {
        // 封装响应
        CheckAllItemResponse response = new CheckAllItemResponse();

        try {
            String checked = request.getChecked();
            String userId = String.valueOf(request.getUserId());

            // 获取购物车map
            RMap<Object, Object> itemsMap = redissonClient.getMap(userId);
            // 遍历map设置所有项目的check
            for (Map.Entry<Object, Object> entry : itemsMap.entrySet()) {
                CartProductDto cartProductDto = (CartProductDto) entry.getValue();
                cartProductDto.setChecked(checked);
                entry.setValue(cartProductDto);
            }

            // 封装响应
            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());

        } catch (Exception e) {
            log.error("ICatServiceImpl.checkAllCartItem Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    /**
     * 删除购物车中的商品
     * @param request 请求参数
     * @return DeleteCartItemResponse
     */
    @Override
    public DeleteCartItemResponse deleteCartItem(DeleteCartItemRequest request) {
        // 响应封装类
        DeleteCartItemResponse response = new DeleteCartItemResponse();
        try {
            String userId = String.valueOf(request.getUserId());
            String itemId = String.valueOf(request.getItemId());

            // 获取购物车map
            RMap<Object, Object> itemsMap = redissonClient.getMap(userId);
            itemsMap.fastRemove(itemId); // 移除项目

            // 封装响应
            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());

        } catch (Exception e) {
            log.error("ICatServiceImpl.deleteCartItem Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    /**
     * 删除选中的商品
     * @param request 请求参数
     * @return DeleteCheckedItemResposne
     */
    @Override
    public DeleteCheckedItemResponse deleteCheckedItem(DeleteCheckedItemRequest request) {
        // 响应封装类
        DeleteCheckedItemResponse response = new DeleteCheckedItemResponse();

        try {
            String userId = String.valueOf(request.getUserId());

            RMap<Object, Object> itemsMap = redissonClient.getMap(userId);

            // 删除所有checked位为true的项目
            Iterator<Map.Entry<Object, Object>> iterator = itemsMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<Object, Object> next = iterator.next();
                CartProductDto cartProductDto = (CartProductDto) next.getValue();
                if ("true".equals(cartProductDto.getChecked())) {
                    iterator.remove();
                }
            }
            // 封装响应
            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            log.error("ICatServiceImpl.deleteCheckedItem Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    /**
     * 清空指定用户的购物车缓存(用户下完订单之后清理）
     * @param request 请求参数
     * @return ClearCartItemResponse
     */
    @Override
    public ClearCartItemResponse clearCartItemByUserID(ClearCartItemRequest request) {
        // 响应封装类
        ClearCartItemResponse response = new ClearCartItemResponse();

        try {
            String userId = String.valueOf(request.getUserId());
            RMap<Object, Object> itemsMap = redissonClient.getMap(userId);
            if (itemsMap.delete())
                throw new BizException(ShoppingRetCode.DB_EXCEPTION.getCode(), ShoppingRetCode.DB_EXCEPTION.getMessage());

        } catch (Exception e) {
            log.error("ICatServiceImpl.ClearCartItemResponse Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }
}
